package com.tianji.learning.service.impl;

import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domin.po.PointsRecord;
import com.tianji.learning.domin.vo.SignResultVO;
import com.tianji.learning.service.ISignRecordsServer;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import static com.tianji.learning.constants.RedisConstants.SIGN_RECORD_KEY_PREFIX;

@Service
@RequiredArgsConstructor
public class SignRecordsServerImpl implements ISignRecordsServer {

    private final StringRedisTemplate redisTemplate;
    private final RabbitMqHelper mqHelper;

    //签到
    @Override
    public SignResultVO sign() {

        //获取用户id
        Long userId = UserContext.getUser();
        //拼接key
        LocalDate now = LocalDate.now();
        String nowDate = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = SIGN_RECORD_KEY_PREFIX + userId + nowDate;
        //签到
        int offset = now.getDayOfMonth() - 1;
        Boolean aBoolean = redisTemplate.opsForValue().setBit(key, offset, true);

        if (Boolean.TRUE.equals(aBoolean)) {
            throw new BadRequestException("重复签到");
        }
        //计算连续签到天数
        int Days = countSignDays(key, now.getDayOfMonth());
        //奖励
        int rewardPoints = 0;
        switch (Days) {
            case 7:
                rewardPoints = 10;
                break;
            case 14:
                rewardPoints = 20;
                break;
            case 28:
                rewardPoints = 40;
                break;
        }
        //封装VO返回
        SignResultVO signResultVO = new SignResultVO();
        signResultVO.setSignDays(Days);
        signResultVO.setRewardPoints(rewardPoints);
        PointsRecord pointsRecord = new PointsRecord();
        pointsRecord.setUserId(userId);
        pointsRecord.setPoints(rewardPoints + 1);
        //发送积分记录
        mqHelper.send(MqConstants.Exchange.LEARNING_EXCHANGE, MqConstants.Key.SIGN_IN, pointsRecord);

        return signResultVO;
    }

    @Override
    public List<Integer> getSignRecords() {

        //获取用户id
        Long userId = UserContext.getUser();
        //拼接key
        LocalDate now = LocalDate.now();
        String nowDate = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
        String key = SIGN_RECORD_KEY_PREFIX + userId + nowDate;
        //查询
        int day = now.getDayOfMonth();
        List<Integer> signDay = new ArrayList<>();

        for (int i = 0; i < day; i++) {
            Boolean bit = redisTemplate.opsForValue().getBit(key, i);
            signDay.add(Boolean.TRUE.equals(bit) ? 1 : 0);
        }

        return signDay;
    }

    private int countSignDays(String key, int dayOfMonth) {

        List<Long> longs = redisTemplate.opsForValue().bitField(key, BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)).valueAt(0));

        if (CollUtils.isEmpty(longs)) {
            return 0;
        }
        Long num = longs.get(0);
        System.out.println(num);
        int count = 0;
        while ((num & 1) == 1) {
            count++;
            num = num >>> 1;
        }
        return count;
    }
}
